#ifndef _OBJECTS_H
#define _OBJECTS_H
#include "Common.h"

class CacheItem;
class Item;

#pragma pack(push)
#pragma pack(1)
struct Item
{
public:
    static void InitGlobalLock();
    static void DestroyGlobalLock();

    u32 len;
    u16 ref_count;
    u8 deleted;
    u8 inner_data;
    CacheItem* cache;
    u64 real_pos;
    char data[0];

    u8 KeyLength() {return (len>>24);}
    u32 ValLength() {return (len&0x00ffffff);}
    void Init(u8 key_len, u32 val_len) 
    {
        len = (key_len<<24)|val_len; 
        ref_count = 0;
        deleted = 0;
        inner_data = 0;
        cache = NULL;real_pos = -1;
    }

    void Init(u32 init_len) 
    {
        len = init_len; 
        ref_count = 0;
        deleted = 0;
        inner_data = 0;
        cache = NULL;real_pos = -1;
    }

    void SetKeyLength(u8 key_len) {len &= 0x00ffffff; len |= (key_len<<24);}
    void SetValLength(u32 val_len) {len &= 0xff000000; len |= val_len;}

    void GetRef()
    {
        lock.Lock();
        ref_count++;
        lock.UnLock();
    }

    void Delete()
    {
        lock.Lock();
        if (ref_count <= 1)
            myfree(this);
        else
        {
            deleted = 1;
            ref_count--;
        }
        lock.UnLock();
    }

    void ReleaseRef()
    {
        lock.Lock();
        ref_count--;
        if (ref_count == 0 && deleted)
            myfree(this);
        lock.UnLock();
    }

    static SpinLock lock;
};
#pragma pack(pop)


#pragma pack(push)
#pragma pack(1)
struct CacheItem
{
    static void InitGlobalLock();
    static void DestroyGlobalLock();

    CacheItem *next;
    CacheItem *prev;
    u16 ref_count;
    u16 deleted;
    Item *item;
    char data[0];

    void Init() 
    {
        ref_count = 0;
        deleted = 0;
    }

    void GetRef()
    {
        lock.Lock();
        ref_count++;
        lock.UnLock();
    }

    void Delete()
    {
        lock.Lock();
        if (ref_count <= 1)
            myfree(this);
        else
        {
            deleted = 1;
            ref_count--;
        }
        lock.UnLock();
    }

    void ReleaseRef()
    {
        lock.Lock();
        ref_count--;
        if (ref_count == 0 && deleted)
            myfree(this);
        lock.UnLock();
    }
     static SpinLock lock;
};
#pragma pack(pop)



#endif

